import sqlalchemy
from flask_restful import fields
from sqlalchemy import types

from . import db

# alias common names
# BigInteger = db.BigInteger().with_variant(sqlite.INTEGER(), 'sqlite')  # type: sqlalchemy.types.BigInteger
BigInteger = db.BigInteger  # type: sqlalchemy.types.BigInteger
Char = db.CHAR
Boolean = db.Boolean  # type: sqlalchemy.types.Boolean
Date = db.Date  # type: sqlalchemy.types.Date
Enum = db.Enum  # type: sqlalchemy.types.Enum
Float = db.Float  # type: sqlalchemy.types.Float
ForeignKey = db.ForeignKey  # type: sqlalchemy.schema.ForeignKey
Integer = db.Integer  # type: sqlalchemy.types.Integer
Interval = db.Interval  # type: sqlalchemy.types.Interval
Numeric = db.Numeric  # type: sqlalchemy.types.Numeric
SmallInteger = db.SmallInteger  # type: sqlalchemy.types.SmallInteger
String = db.String  # type: sqlalchemy.types.String
Text = db.Text  # type: sqlalchemy.types.Text
Time = db.Time  # type: sqlalchemy.types.Time
UniqueConstraint = db.UniqueConstraint


class DateTime(types.TypeDecorator):
    impl = types.DateTime

    def __init__(self, *args, **kwargs):
        kwargs['timezone'] = True
        super().__init__(*args, **kwargs)

    def process_bind_param(self, value, dialect):
        if value is not None:
            if value.tzinfo is None:
                raise ValueError('Cannot persist timezone-naive datetime')
            # return value.astimezone(pytz.UTC)
            return value

    def process_result_value(self, value, dialect):
        if value is not None:
            return value
            # return value.astimezone(pytz.UTC)


FIELD_TYPE_DICT = {
    Integer: fields.Integer,
    Float: fields.Float,
    SmallInteger: fields.Integer,
    Text: fields.String,
    String: fields.String,
    Numeric: fields.Float,
}

DE_FIELD_TYPE_DICT = {
    Integer: fields.Integer,
    Float: fields.Float,
    SmallInteger: fields.Integer,
    Text: fields.String,
    String: fields.String,
    Numeric: fields.Float,
}
